import random
import pygame

# 背景
BACKGROUND_IMAGE = 'background.png'
# 屏幕大小常量
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
# 刷新帧率
FRAME_RATE = 60
# 敌机定时器常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
# 英雄发射子弹定时器常量
HERO_FIRE_EVENT = pygame.USEREVENT + 1
# 敌机图片
ENEMY_IMAGE = 'enemy1.png'
# 敌机销毁图片
ENEMY_DESTROY_IMAGE = 'enemy1_down3.png'
# 英雄图片
HERO_IMAGE = 'hero1.png'
# 英雄销毁图片
HERO_DESTROY_IMAGE = 'hero_destroy_3.png'
# 子弹图片
BULLET_IMAGE = 'bullet1.png'


class GameSprite(pygame.sprite.Sprite):
    def __init__(self, image_name, position=(0, 0), speed=1):
        # 调用父类初始化方法
        super().__init__()

        # 定义对象属性
        self.image = pygame.image.load('./images/' + image_name)
        self.rect = self.image.get_rect()
        self.rect.x = position[0]
        self.rect.y = position[1]
        self.speed = speed

    def update(self):
        # 屏幕垂直方向移动
        self.rect.y += self.speed

    def set_image(self, image_name):
        # 更换精灵图图片
        self.image = pygame.image.load('./images/' + image_name)


class Background(GameSprite):
    """背景类"""

    def __init__(self, is_first=False):
        # 1、调用父类初始化方法
        super().__init__(BACKGROUND_IMAGE)
        # 2、判断是否是第一张背景图对象
        if not is_first:
            self.rect.y = -self.rect.height

    def update(self):
        # 1、调用父类update方法实现移动
        super().update()
        # 2、边界检测
        # 2.1、如果移出屏幕，则初始化背景图像，既y值为-heiht
        if self.rect.y >= SCREEN_RECT.height:
            self.rect.y = -SCREEN_RECT.height


class Enemy(GameSprite):
    """敌机精灵类"""

    def __init__(self):
        # 1、调用父类方法，创建敌机精灵，并指定敌机图片
        super().__init__(ENEMY_IMAGE)
        # 2、指定敌机初始速度
        self.speed = random.randint(1, 3)
        # 3、指定敌机初始位置
        self.rect.bottom = 0
        self.rect.x = random.randint(0, SCREEN_RECT.width - self.rect.width)

    def update(self):
        # 1、调用父类方法，实现移动
        super().update()
        # 2、边界检测
        if self.rect.y >= SCREEN_RECT.height:
            # 删除敌机精灵-kill()方法将精灵冲所有精灵组中销毁
            self.kill()


class Hero(GameSprite):
    """英雄精灵类"""

    def __init__(self):
        # 1、设置英雄图片
        # 2、初始化移动速度0
        super().__init__(HERO_IMAGE, speed=0)
        # 3、初始化英雄位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 120
        # 4、初始化一个子弹精灵组
        self.bullet_group = pygame.sprite.Group()

    def update(self):
        # 1、英雄在水平方向移动
        self.rect.x += self.speed
        # 2、边界检测：不能移出边界
        if self.rect.left <= 0:
            self.rect.left = 0
        if self.rect.right >= SCREEN_RECT.right:
            self.rect.right = SCREEN_RECT.right

    def adjust_speed(self, speed=0):
        # 调整英雄速度
        self.speed = speed

    def fire(self):
        # 英雄发射子弹,每次发射三颗子弹 TODO
        # print("发射子弹……")
        for i in range(3):
            # 1、创建子弹
            bullet = Bullet()
            position = (self.rect.centerx, self.rect.y)
            # 2、初始化子弹位置
            bullet.adjust_position(position, i)
            # 3、子弹精灵组添加子弹
            self.bullet_group.add(bullet)
        pass

    def update_bullet_group(self, screen):
        # 绘制/更正子弹精灵组
        self.bullet_group.update()
        self.bullet_group.draw(screen)

    def get_bullet_group(self):
        # 获取子弹精灵组
        return self.bullet_group


class Bullet(GameSprite):
    """子弹精灵类"""

    def __init__(self):
        # 1、设置子弹图片
        # 2、设置子弹移动方向和速度
        super().__init__(BULLET_IMAGE, speed=-2)
        # 3、设置子弹初始位置:英雄正上方,由英雄设置

    def update(self):
        # 1、子弹向正上方移动
        super().update()
        # 2、边界检测：子弹走出上边界，则销毁子弹
        if self.rect.bottom <= 0:
            self.kill()

    def adjust_position(self, position=(0, 0), seq=0):
        # 调整子弹位置
        self.rect.centerx = position[0]
        self.rect.y = position[1] - (seq * 20)
